package com.t.bricks.bussiness.db.dao.coupon.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.t.bricks.bussiness.db.dao.coupon.CouponDao;
import com.t.bricks.bussiness.db.entity.coupon.Coupon;
import com.t.bricks.bussiness.db.entity.coupon.base.CouponBase;
import com.t.bricks.bussiness.db.mapper.coupon.CouponMapper;
import com.t.bricks.bussiness.model.coupon.ConditionCoupon;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.model.OrderInfoList;
import com.t.bricks.model.Page;
import com.t.bricks.utils.function.data.IntegerUtil;
import com.t.bricks.utils.function.data.U62Util;

@Repository
public class CouponDaoImpl implements CouponDao {
	
	@Autowired
	private CouponMapper couponMapper;

	@Value("${app.findPage.dLikeDate:配置文件中的当前库全文检索时间范围dLikeDate未设置}")
	private String sLikeDate;

	/**
	 * 批量添加
	 * @param coupon
	 * @param iSize
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity adds(Coupon coupon, int iSize) {
		int k = 0;
		while(iSize > 0) {
			k = iSize > 1000 ? 1000 : iSize;
			List<String> sNos = U62Util.getUids(k);

			try {
				int i = couponMapper.adds(coupon, sNos);
				if (i < 1) {
					Log.error("批量新增未能得到预期影响值(预期", sNos.size(), "):", i);
					return new MsgEmity(false, "新增数据失败！", 7001);
				}
				
				iSize = iSize - k;
				
				if (iSize <= 0) {
					break;
				}
				
				Thread.sleep(1000);
			} catch (Exception e) {
				Log.error("批量新增时发生异常:", e.getMessage());
				return new MsgEmity(false, "批量新增失败！", 7002);
			}
		}
		
		return new MsgEmity(true, "批量新增成功！", 7999);
	}

	/**
	 * 删除
	 * 注:只能删除未被领取的数据
	 * @param uId 记录编号
	 * @param iVersion 数据版本号
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity del(String uId, Integer iVersion) {
		try {
			int i = couponMapper.del(uId, iVersion);
			if (i < 1) {
				List<String> fieldNames = Arrays.asList("iVersion", "sCustomerId");
				Map<String, Object> map = couponMapper.getValueByFieldName(uId, fieldNames);//如果删除的影响数小于1,则检查数据是否存在
				if (null == map) {
					return new MsgEmity(true, "成功，数据已经删除！", 7999);//删除影响数失败,但数据也不存在则视为成功
				}
				
				if (!iVersion.equals(map.get("iVersion"))) {
					return new MsgEmity(false, "删除数据失败，系统中的数据可能已经被更新！", 7001);
				}
				
				if (null != map.get("sCustomerId")) {
					return new MsgEmity(false, "删除数据失败，被领取的优惠卷不能删除！", 7004);
				}

				Log.error("删除未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "删除数据失败！", 7002);
			}
		} catch (Exception e) {
			Log.error("删除时发生异常:", e.getMessage());
			return new MsgEmity(false, "删除失败！", 7003);
		}
		
		return new MsgEmity(true, "删除成功！", 7999);
	}
	
	/**
	 * 根据Id查询数据
	 * @param uId
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findById(String uId) {
		Coupon coupon = null;
		try {
			coupon = couponMapper.findById(uId);
			if (null == coupon) {
				return new MsgEmity(false, "数据不存在！", 7001);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", coupon);
	}

	/**
	 * 根据字段名取指定记录编号的数据库表中对应字段的值
	 * @param uId
	 * @param fieldNames 待取数据的字段名称集合
	 * @return MsgEmity 返回内容data中存放的是Map
	 */
	@Override
	public MsgEmity getValueByFieldName(String uId, List<String> fieldNames) {
		//--检查实体类中是否有该字段,没有就不加入查询字段--//
		Class<?> clazz = CouponBase.class;
		List<String> dbNames = new ArrayList<String>();
		for (String field : fieldNames) {
			try {
				if (clazz.getDeclaredField(field) != null) {
					dbNames.add(field);
				}
			} catch (Exception e) {
			}
		}
		
		if (dbNames.size() < 1) {
			return new MsgEmity(false, "没有对应的数据可查询！", 7001);
		}
		
		Map<String, Object> result = null;
		try {
			result = couponMapper.getValueByFieldName(uId, dbNames);
			if (null == result) {
				return new MsgEmity(false, "数据不存在！", 7002);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7003);
		}
		
		//--补充字段--//
		for (String string : fieldNames) {
			if (!result.containsKey(string)) {
				result.put(string, null);
			}
		}
		
		return new MsgEmity(true, "查询成功！", result);
	}

	/**
	 * 根据关键值取对象集合
	 * @param couponData 存放查询条件的Coupon对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByKey(Coupon couponData) {
		List<Coupon> list = null;
		try {
			list = couponMapper.findByKey(couponData);
			if (null == list) {
				return new MsgEmity(false, "数据不存在！", 7001);
			}
			if (list.size() < 1) {
				return new MsgEmity(true, "查询成功，但没有数据！", list);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", list);
	}

	/**
	 * 根据关键值查数量
	 * @param couponData 存放查询条件的Coupon对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findCountByKey(Coupon couponData) {
		int iCount = 0;
		try {
			iCount = couponMapper.findCountByKey(couponData);
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7001);
		}
		
		return new MsgEmity(true, "查询成功！", iCount);
	}
	
	/**
	 * 查询分页信息
	 * @param page 分页信息对象
	 * @param orders 排序数据集合
	 * @param sLikeStr 全文检索
	 * @param condition 查询条件对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByPage(Page page, OrderInfoList orders, String sLikeStr,
			ConditionCoupon condition) {
		if ("配置文件中的当前库全文检索时间范围dLikeDate未设置".equals(sLikeDate)) {
			sLikeDate = "3";
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DATE, - IntegerUtil.strToInt(sLikeDate, 3));//日期加m天
		Date dLikeDateSt = calendar.getTime();
		Date dLikeDateEd = new Date();
		
		int iCount = 0;
		try {
			iCount = couponMapper.findByPageCount(sLikeStr, dLikeDateSt, dLikeDateEd, condition);
		} catch (Exception e) {
			Log.error("查询数量发生异常", e.getMessage());
			return new MsgEmity(false, "查询数量失败！", 7001);
		}
		
		if (iCount < 1) {
			return new MsgEmity(true, "没有相关数据！", page);
		}

		page.setCountRow(iCount);

		List<Coupon> list = null;
		try {
			list = couponMapper.findByPage(page,
					(null == orders) ? null : orders.getOrderInfoList(),
					sLikeStr, dLikeDateSt, dLikeDateEd, condition);
			if (null == list) {
				Log.error("查询数据发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7002);
			}
		} catch (Exception e) {
			Log.error("查询分页数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7003);
		}

		page.setRecordList(list);
		
		if (null != sLikeStr) {
			return MsgEmity.success(page, "查询成功！", "由于使用了全文检索,因此数据查询限制为近", sLikeDate, "天创建的数据");
		}
		
		return new MsgEmity(true, "查询成功！", page);
	}
	
	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param uId 记录编号
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByPageRow(String uId) {
		Coupon coupon = null;
		try {
			coupon = couponMapper.findByPageRow(uId);
			if (null == coupon) {
				return new MsgEmity(false, "数据不存在！", 7001);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", coupon);
	}
	
	/**
	 * 查询搜索用的数据
	 * 警告:本方法只允许内部使用,不能开放到外部接口
	 * @param whereStr 查询条件字符串
	 * @param orders 排序数据集合
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findBySearch(String whereStr, OrderInfoList orders) {
		if (null == whereStr || "".equals(whereStr.trim())) {
			return new MsgEmity(false, "查询条件不允许为空！", 7001);
		}

		List<Coupon> list = null;
		try {
			list = couponMapper.findBySearch(whereStr.trim(),
					(null == orders) ? null : orders.getOrderInfoList());
			if (null == list) {
				Log.error("查询数据发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7002);
			}
		} catch (Exception e) {
			Log.error("查询分页数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7003);
		}
		
		return new MsgEmity(true, "查询成功！", list);
	}

	/**
	 * 查询导出到文件的数据
	 * @param orders 排序数据集合
	 * @param sLikeStr 全文检索
	 * @param condition 查询条件对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByExport(OrderInfoList orders, String sLikeStr, ConditionCoupon condition) {
		if ("配置文件中的当前库全文检索时间范围dLikeDate未设置".equals(sLikeDate)) {
			sLikeDate = "3";
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DATE, - IntegerUtil.strToInt(sLikeDate, 3));//日期加m分
		Date dLikeDateSt = calendar.getTime();
		Date dLikeDateEd = new Date();
		
		List<Coupon> list = null;
		try {
			list = couponMapper.findByExport(
					(null == orders) ? null : orders.getOrderInfoList(),
					sLikeStr, dLikeDateSt, dLikeDateEd, condition);
			if (null == list) {
				Log.error("查询数据发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7001);
			}
		} catch (Exception e) {
			Log.error("查询导出文件用的数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", list);
	}

	//----------------------------- 自动生成代码结束 ---------------------------//

	/**
	 * 批量删除数据
	 * 注:只能删除未被领取的数据
	 * @param sType 分类
	 * @param sWaresType 限制商品分类
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity dels(String sType, String sWaresType) {
		try {
			int i = couponMapper.dels(sType, sWaresType);
			if (i < 1) {
				Log.error("删除操作执行成功但未能得到预期影响值(预期>0):", i);
				return new MsgEmity(true, "删除操作执行成功但未能得到预期影响值(预期>0)", i);
			}
			
			return new MsgEmity(true, "删除成功(只能删除未被领取的卷)！", i);
		} catch (Exception e) {
			Log.error("删除时发生异常:", e.getMessage());
			return new MsgEmity(false, "删除失败！", 7003);
		}
	}

	/**
	 * 占用(一张)
	 * @param sType 分类
	 * @param mPrice 金额
	 * @param sCustomerId 客户编号
	 * @return
	 */
	@Override
	public MsgEmity employ(String sType, BigDecimal mPrice, String sCustomerId) {
		try {
			int i = couponMapper.employ(sType, mPrice, sCustomerId);
			if (i < 1) {
				Log.error("按分类与金额占用操作执行成功但未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "按分类与金额占用操作执行成功但未能得到预期影响值(预期1)", 7001);
			}
			
			return new MsgEmity(true, "按分类与金额占用操作执行成功！", 7999);
		} catch (Exception e) {
			Log.error("按分类与金额占用操作时发生异常:", e.getMessage());
			return new MsgEmity(false, "按分类与金额占用操作失败！", 7003);
		}
	}

	/**
	 * 按编号占用
	 * @param uId 记录编号
	 * @param sCustomerId 客户编号
	 * @param iVersion 当前版本号
	 * @return
	 */
	@Override
	public MsgEmity employById(String uId, String sCustomerId, Integer iVersion) {
		try {
			int i = couponMapper.employById(uId, sCustomerId, iVersion);
			if (i < 1) {
				Log.error("按编号占用操作执行成功但未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "占用操作执行成功但未能得到预期影响值(预期1)", 7001);
			}
			
			return new MsgEmity(true, "占用操作执行成功！", 7999);
		} catch (Exception e) {
			Log.error("按编号占用操作发生异常:", e.getMessage());
			return new MsgEmity(false, "按编号占用操作失败！", 7003);
		}
	}
	
	/**
	 * 将过期数据更新状态
	 * @return
	 */
	@Override
	public MsgEmity expire() {
		try {
			int i = couponMapper.expire();
			return MsgEmity.success(i, "检查过期数据执行成功,影响数:");
		} catch (Exception e) {
			Log.error("检查过期数据时发生异常:", e.getMessage());
			return new MsgEmity(false, "检查过期数据失败！", 7003);
		}
	}
	
	/**
	 * 查询顾客所持优惠卷
	 * @param sType
	 * @param mPrice
	 * @param iState
	 * @param sCustomerId
	 * @return MsgEmity List<Coupon>
	 */
	@Override
	public MsgEmity findByCustomer(String sType, BigDecimal mPrice,
			Integer iState, String sCustomerId) {
		try {
			List<Coupon> list = couponMapper.findByCustomer(sType, mPrice, iState, sCustomerId);
			if (null == list) {
				Log.error("查询顾客所持优惠卷发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7001);
			}
			
			return new MsgEmity(true, "查询成功！", list);
		} catch (Exception e) {
			Log.error("查询顾客所持优惠卷发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7002);
		}
	}

}
